package com.zzw.utils;

import com.zzw.bean.CabinetStatus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 柜机数据解析工具类
 */
public class CabinetParser {
    private static final Logger logger = LoggerFactory.getLogger(CabinetParser.class);

    /**
     * 解析柜机状态数据
     *
     * @param data 十六进制数据
     * @return 柜机状态对象
     */
    public static CabinetStatus parse(byte[] data) {
        try {
            if (data == null || data.length < 5) {
                logger.error("数据长度不足");
                return null;
            }

            // 创建柜机状态对象
            CabinetStatus status = new CabinetStatus();

            // 解析头码
            status.setHeader(data[0]);

            // 解析数据包长度
            status.setLength(((data[1] & 0xFF) << 8) | (data[2] & 0xFF));

            // 验证数据包长度
            if (data.length < status.getLength() + 4) {
                logger.error("数据包长度不匹配");
                return null;
            }

            // 解析命令
            status.setCommand(data[3]);

            // 解析机芯数量
            int coreCount = data[4] & 0xFF;

            // 当前数据位置
            int pos = 5;

            // 解析每个机芯数据
            for (int i = 0; i < coreCount; i++) {
                CabinetStatus.CoreStatus core = new CabinetStatus.CoreStatus();

                // 解析机芯地址
                core.setAddress(data[pos++]);

                // 解析机芯温度
                core.setTemperature(data[pos++] & 0xFF);

                // 解析软件版本
                core.setSoftwareVersion(data[pos++] & 0xFF);

                // 解析硬件版本
                core.setHardwareVersion(data[pos++] & 0xFF);

                // 解析充电宝数量
                int powerBankCount = data[pos++] & 0xFF;

                // 解析每个充电宝数据
                for (int j = 0; j < powerBankCount; j++) {
                    CabinetStatus.PowerBankStatus powerBank = new CabinetStatus.PowerBankStatus();

                    // 解析孔位
                    powerBank.setSlot(data[pos++] & 0xFF);

                    // 解析状态信息
                    powerBank.setStatus(data[pos++] & 0xFF);

                    // 解析放电电流
                    powerBank.setDischargeCurrent(((data[pos] & 0xFF) << 8 | (data[pos + 1] & 0xFF)) / 100.0);
                    pos += 2;

                    // 解析电芯电压
                    powerBank.setCellVoltage(((data[pos] & 0xFF) << 8 | (data[pos + 1] & 0xFF)) / 100.0);
                    pos += 2;

                    // 解析区域码
                    powerBank.setAreaCode(data[pos++]);

                    // 解析充电宝SN
                    long sn = 0;
                    for (int k = 0; k < 8; k++) {
                        sn = (sn << 8) | (data[pos + k] & 0xFF);
                    }
                    powerBank.setSerialNumber(sn);
                    pos += 8;

                    // 解析电量
                    powerBank.setBatteryLevel(data[pos++] & 0xFF);

                    // 解析温度
                    powerBank.setTemperature(data[pos++] & 0xFF);

                    // 解析充电电压
                    powerBank.setChargeVoltage(((data[pos] & 0xFF) << 8 | (data[pos + 1] & 0xFF)) / 100.0);
                    pos += 2;

                    // 解析充电电流
                    powerBank.setChargeCurrent(((data[pos] & 0xFF) << 8 | (data[pos + 1] & 0xFF)) / 100.0);
                    pos += 2;

                    // 解析软件版本
                    powerBank.setSoftwareVersion(data[pos++] & 0xFF);

                    // 解析孔位检测状态
                    powerBank.setSlotStatus(data[pos++]);

                    // 添加到机芯的充电宝列表
                    core.getPowerBanks().add(powerBank);
                }

                // 添加到柜机的机芯列表
                status.getCores().add(core);
            }

            // 解析校验码
            status.setChecksum(data[pos]);

            // 验证校验码
            byte calculatedChecksum = calculateChecksum(data, 0, pos);
            if (calculatedChecksum != status.getChecksum()) {
                logger.error("校验码不匹配: 计算值={}, 实际值={}", calculatedChecksum, status.getChecksum());
                return null;
            }

            return status;
        } catch (Exception e) {
            logger.error("解析柜机状态数据异常: {}", e.getMessage(), e);
            return null;
        }
    }

    /**
     * 计算校验码
     */
    private static byte calculateChecksum(byte[] data, int start, int end) {
        byte sum = 0;
        for (int i = start; i < end; i++) {
            sum ^= data[i];
        }
        return sum;
    }
}
